# !/usr/bin/env python
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
   File Name:     allure_handler.py
   Description:   企业级 JSON 操作工具类
-------------------------------------------------
"""
import json
from pathlib import Path
from typing import Any, Optional, Union
import logging

# 模块公开接口
__all__ = ["JSONHandler", "json_handler"]

from jsonpath import jsonpath

# Configure logging
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(name)s - %(message)s",
)
logger = logging.getLogger("JSONHandler")


class JSONHandler:
    """
    企业级 JSON 操作工具类
    提供读取、写入、格式化和验证 JSON 的统一接口。
    """

    @staticmethod
    def read_json_file(filepath: Union[str, Path]) -> Any:
        """
        读取 JSON 文件并解析为 Python 对象。

        :param filepath: JSON 文件路径
        :return: Python 对象（通常是 dict 或 list）
        :raises FileNotFoundError: 文件不存在
        :raises json.JSONDecodeError: JSON 格式错误
        """
        filepath = Path(filepath)
        logger.info(f"Reading JSON file: {filepath}")
        if not filepath.exists():
            logger.error(f"File not found: {filepath}")
            raise FileNotFoundError(f"File not found: {filepath}")

        try:
            with open(filepath, "r", encoding="utf-8") as file:
                data = json.load(file)
                logger.debug(f"JSON file loaded successfully: {filepath}")
                return data
        except json.JSONDecodeError as e:
            logger.error(f"Failed to decode JSON file: {filepath} | Error: {e}")
            raise

    @staticmethod
    def write_json_file(filepath: Union[str, Path], data: Any, indent: Optional[int] = 4) -> None:
        """
        将 Python 对象写入 JSON 文件。

        :param filepath: JSON 文件路径
        :param data: Python 对象（通常是 dict 或 list）
        :param indent: 缩进级别，用于格式化输出
        """
        filepath = Path(filepath)
        logger.info(f"Writing JSON to file: {filepath}")
        try:
            with open(filepath, "w", encoding="utf-8") as file:
                json.dump(data, file, ensure_ascii=False, indent=indent)
                logger.debug(f"JSON file written successfully: {filepath}")
        except Exception as e:
            logger.error(f"Failed to write JSON to file: {filepath} | Error: {e}")
            raise

    @staticmethod
    def serialize_to_json_string(data: Any, indent: Optional[int] = 4) -> str:
        """
        将 Python 对象序列化为 JSON 格式字符串。

        :param data: Python 对象
        :param indent: 缩进级别，用于格式化输出
        :return: JSON 格式的字符串
        """
        logger.info("Serializing Python object to JSON string")
        try:
            json_string = json.dumps(data, ensure_ascii=False, indent=indent)
            logger.debug("Python object serialized to JSON string successfully")
            return json_string
        except TypeError as e:
            logger.error(f"Failed to serialize object to JSON string | Error: {e}")
            raise

    @staticmethod
    def validate_json_schema(data: Any, schema: dict) -> bool:
        """
        验证 JSON 数据是否符合指定的 JSON Schema。

        :param data: 要验证的 JSON 数据
        :param schema: JSON Schema 字典
        :return: True 如果数据符合 Schema，否则引发异常
        :raises jsonschema.ValidationError: 如果数据不符合 Schema
        """
        try:
            from jsonschema import validate
            logger.info("Validating JSON data against schema")
            validate(instance=data, schema=schema)
            logger.debug("JSON data is valid")
            return True
        except ImportError as e:
            logger.error("jsonschema module is not installed")
            raise ImportError("Please install jsonschema module to use this feature") from e
        except Exception as e:
            logger.error(f"JSON data validation failed | Error: {e}")
            raise

    @staticmethod
    def pretty_print_json(data: Any) -> None:
        """
        格式化输出 JSON 数据到控制台。

        :param data: Python 对象（通常是 dict 或 list）
        """
        logger.info("Pretty printing JSON data")
        try:
            print(json.dumps(data, ensure_ascii=False, indent=4))
        except TypeError as e:
            logger.error(f"Failed to pretty print JSON data | Error: {e}")
            raise

    @staticmethod
    def parse_json_string(json_string: str) -> Any:
        """
        将 JSON 字符串解析为 Python 对象。

        :param json_string: JSON 格式的字符串
        :return: Python 对象
        :raises json.JSONDecodeError: JSON 格式错误
        """
        logger.info("Parsing JSON string")
        try:
            data = json.loads(json_string)
            logger.debug("JSON string parsed successfully")
            return data
        except json.JSONDecodeError as e:
            logger.error(f"Failed to decode JSON string | Error: {e}")
            raise

    @staticmethod
    def jsonpath_query(data: Any, jsonpath_expression: str) -> list:
        """
        使用 JSONPath 表达式查询 JSON 数据。

        :param data: JSON 数据
        :param jsonpath_expression: JSONPath 表达式
        :return: 查询结果列表
        :raises ValueError: 如果查询失败或未找到结果
        """
        logger.info(f"执行 JSONPath 查询: {jsonpath_expression}")
        try:
            results = jsonpath(data, jsonpath_expression)
            if results is False or not results:  # jsonpath 返回 False 表示未找到结果
                logger.warning(f"没有找到 JSONPath 的结果: {jsonpath_expression}")
                return []
            logger.info(f"JSONPath 查询结果: {results}")
            return results
        except Exception as exp:
            logger.error(f"无法执行 JSONPath 查询: {jsonpath_expression} | Error: {exp}")
            raise ValueError(f"JSONPath 表达式无效或查询失败: {jsonpath_expression}") from exp


# 全局实例化，便于外部调用
json_handler = JSONHandler()

# 示例用法
if __name__ == "__main__":
    # 读取 JSON 文件
    try:
        data = JSONHandler.read_json_file("example.json")
        JSONHandler.pretty_print_json(data)
    except Exception as e:
        logger.error(e)

    # 写入 JSON 文件
    example_data = {"name": "Alice", "age": 30, "languages": ["English", "Chinese"]}
    try:
        JSONHandler.write_json_file("output.json", example_data)
    except Exception as e:
        logger.error(e)

    # JSON 字符串解析
    json_str = '{"name": "Bob", "age": 25}'
    try:
        parsed_data = JSONHandler.parse_json_string(json_str)
        logger.info(parsed_data)
    except Exception as e:
        logger.error(e)

    # 序列化 Python 对象为 JSON 字符串
    try:
        json_string = JSONHandler.serialize_to_json_string(example_data)
        logger.info(json_string)
    except Exception as e:
        logger.error(e)
